package org.teamh.gui.ingame;

import org.lwjgl.util.glu.GLU;

/**
 * This class is responsible for the correct camera movement in the game. 
 * @author richard
 *
 */
public class Camera {
	private static final float SCROLL_DISTANCE_SPEED = 0.12f;
	private static final float SCROLL_ANGLE_SPEED = 3.5f;
	private static final float MIN_ANGLE = (float)Math.toRadians(5);
	private static final float MAX_ANGLE = (float)Math.toRadians(80);
	private static final float TURN_DISTANCE = 1;
	private static final float INIT_DISTANCE = 3;
	
	private float distance = INIT_DISTANCE;
	private double angle = MAX_ANGLE;
	
	private float xPos = 0;
	private float yPos = (float) 2.5;
	private float zPos = (float) 1.5;
	
	public void init() {
		distance = INIT_DISTANCE;
		angle = MAX_ANGLE;
	}
	
	/**
	 * This must be called to make the camera look into the current position. 
	 */
	public void look() {
		updatePosition();
		
		GLU.gluLookAt(xPos, yPos, zPos, 0, 0, 0, 0, 1, 0);
	}
	
	/**
	 * Updates the current position in dependence of the distance and the angle. 
	 */
	private void updatePosition() {
		xPos = 0;
		yPos = (float)Math.sin(angle) * distance;
		zPos = (float)Math.cos(angle) * distance;
	}
	
	/**
	 * Receives mouse wheel movement. 
	 * @param movement
	 */
	public void mouseWheelMoved(int movement) {
		updateDistance(movement);
	}
	
	/**
	 * Scrolls in or out of the scene, or updates the look angel, if the mouse wheel rolls. 
	 * @param movement
	 */
	private void updateDistance(int movement) {
		if(movement > 0) {
			distance -= movement * distance * SCROLL_DISTANCE_SPEED;
			
			if(distance <= TURN_DISTANCE) {
				distance = TURN_DISTANCE;
				
				angle = Math.max(MIN_ANGLE, angle - Math.toRadians(movement * (angle + 0.2f) * SCROLL_ANGLE_SPEED));
			}
		} else {
			angle -= Math.toRadians(movement * (angle + 0.2f) * SCROLL_ANGLE_SPEED);
			
			if(angle >= MAX_ANGLE) {
				angle = MAX_ANGLE;
				
				distance = Math.min(distance - movement * distance * SCROLL_DISTANCE_SPEED, 20);
			}
		}
		
	}
	

}
